package com.graduation.check.service.impl;

import com.graduation.check.dto.LoginRequest;
import com.graduation.check.dto.LoginResponse;
import com.graduation.check.dto.RegisterRequest;
import com.graduation.check.entity.User;
import com.graduation.check.mapper.UserMapper;
import com.graduation.check.service.AuthService;
import com.graduation.check.utils.JwtUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.regex.Pattern;

@Service
public class AuthServiceImpl implements AuthService {

    private final AuthenticationManager authenticationManager;
    private final UserMapper userMapper;
    private final JwtUtil jwtUtil;
    private final PasswordEncoder passwordEncoder;

    // 邮箱正则表达式
    private static final Pattern EMAIL_PATTERN = Pattern.compile("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");

    public AuthServiceImpl(AuthenticationManager authenticationManager,
                           UserMapper userMapper,
                           JwtUtil jwtUtil,
                           PasswordEncoder passwordEncoder) {
        this.authenticationManager = authenticationManager;
        this.userMapper = userMapper;
        this.jwtUtil = jwtUtil;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public LoginResponse login(LoginRequest loginRequest) {
        try {
            // 使用Spring Security进行认证
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            loginRequest.getAccount(),
                            loginRequest.getPassword()
                    )
            );

            SecurityContextHolder.getContext().setAuthentication(authentication);

            // 获取用户信息 - 使用 UserMapper
            User user = userMapper.findByAccount(loginRequest.getAccount());
            if (user == null) {
                throw new RuntimeException("用户不存在");
            }

            // 检查用户状态
            if (user.getStatus() == 0) {
                return LoginResponse.error(400, "用户已被禁用");
            }

            // 生成JWT令牌（包含用户类型）
            String token = jwtUtil.generateToken(loginRequest.getAccount(), user.getUserType());
            Long expiresIn = jwtUtil.getExpiration();

            // 创建用户信息
            LoginResponse.UserInfo userInfo = LoginResponse.createUserInfo(
                    user.getId(),
                    user.getAccount(),
                    user.getName(),
                    user.getUserType(),
                    user.getCreateTime()
            );

            return LoginResponse.success("登录成功", token, expiresIn, userInfo);

        } catch (AuthenticationException e) {
            return LoginResponse.error(401, "账号或密码错误");
        } catch (Exception e) {
            return LoginResponse.error(400, e.getMessage());
        }
    }

    @Override
    public LoginResponse register(RegisterRequest registerRequest) {
        try {
            // 验证注册请求参数
            String validationError = validateRegisterRequest(registerRequest);
            if (validationError != null) {
                return LoginResponse.error(400, validationError);
            }

            // 检查用户名是否已存在 - 使用 UserMapper
            User existingUser = userMapper.findByAccount(registerRequest.getAccount());
            if (existingUser != null) {
                return LoginResponse.error(400, "用户名已存在");
            }

            // 检查邮箱是否已存在 - 需要添加 findByEmail 方法到 UserMapper
            User existingEmail = userMapper.findByEmail(registerRequest.getEmail());
            if (existingEmail != null) {
                return LoginResponse.error(400, "邮箱已被注册");
            }

            // 创建用户实体
            User user = new User();
            user.setName(registerRequest.getName());
            user.setAccount(registerRequest.getAccount());
            user.setEmail(registerRequest.getEmail());
            user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));

            // 设置用户类型（将 student/teacher 转换为 S/T）
            String userType = mapUserTypeToCode(registerRequest.getUserType());
            user.setUserType(userType);

            // 设置专业、班级和部门
            user.setMajor(registerRequest.getMajor());
            user.setClassName(registerRequest.getClassName());
            user.setDepartment(registerRequest.getDepartment());

            user.setStatus(1);
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());

            // 保存用户 - 使用 UserMapper
            userMapper.insert(user);

            // 使用注册成功的响应格式
            return LoginResponse.success(200, "注册成功，请登录", null, null, null);

        } catch (Exception e) {
            e.printStackTrace(); // 添加日志以便调试
            return LoginResponse.error(400, "注册失败: " + e.getMessage());
        }
    }

    @Override
    public LoginResponse logout(HttpServletRequest request) {
        try {
            // 清除Spring Security上下文
            SecurityContextHolder.clearContext();

            // 获取token并加入黑名单（如果使用JWT黑名单机制）
            String token = extractTokenFromRequest(request);
            if (token != null && jwtUtil != null) {
                // 如果有黑名单机制，可以在这里将token加入黑名单
                // jwtUtil.invalidateToken(token);
            }

            return LoginResponse.success(200, "登出成功", null, null, null);
        } catch (Exception e) {
            return LoginResponse.error(400, "登出失败: " + e.getMessage());
        }
    }

    /**
     * 从请求中提取token
     */
    private String extractTokenFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }

    /**
     * 验证注册请求参数
     */
    private String validateRegisterRequest(RegisterRequest request) {
        // 验证真实姓名
        if (!StringUtils.hasText(request.getName())) {
            return "真实姓名不能为空";
        }

        // 验证用户名（学号/工号）
        if (!StringUtils.hasText(request.getAccount())) {
            return "学号/工号不能为空";
        }

        // 验证邮箱
        if (!StringUtils.hasText(request.getEmail())) {
            return "邮箱不能为空";
        }
        if (!isValidEmail(request.getEmail())) {
            return "邮箱格式不正确";
        }

        // 验证密码
        if (!StringUtils.hasText(request.getPassword())) {
            return "密码不能为空";
        }
        if (request.getPassword().length() < 6) {
            return "密码至少6位";
        }

        // 验证用户类型
        if (!StringUtils.hasText(request.getUserType())) {
            return "用户类型不能为空";
        }
        if (!"student".equals(request.getUserType()) && !"teacher".equals(request.getUserType())) {
            return "用户类型必须是 student 或 teacher";
        }

        // 验证学生和教师的必填字段
        if ("student".equals(request.getUserType())) {
            if (!StringUtils.hasText(request.getMajor())) {
                return "学生必须选择专业";
            }
            if (!StringUtils.hasText(request.getClassName())) {
                return "学生必须填写班级";
            }
        } else if ("teacher".equals(request.getUserType())) {
            if (!StringUtils.hasText(request.getDepartment())) {
                return "教师必须选择部门";
            }
        }

        return null;
    }

    /**
     * 将用户类型映射到用户类型代码
     */
    private String mapUserTypeToCode(String userType) {
        if ("student".equals(userType)) {
            return "S"; // 学生
        } else if ("teacher".equals(userType)) {
            return "T"; // 老师
        }
        return userType;
    }

    /**
     * 验证邮箱格式
     */
    private boolean isValidEmail(String email) {
        if (email == null) {
            return false;
        }
        return EMAIL_PATTERN.matcher(email).matches();
    }
}